#ifndef VA_TOOLS_H
#define VA_TOOLS_H

#include "addon.h"

namespace VA
{
  class Tools : public Nan::ObjectWrap
  {
  public:
    static NAN_MODULE_INIT(Init)
    {
      auto className = Nan::New("Tools").ToLocalChecked();
      auto tpl = Nan::New<v8::FunctionTemplate>(New);
      tpl->SetClassName(className);
      tpl->InstanceTemplate()->SetInternalFieldCount(1);

      CUSTOM_NAN_SET_PROTOTYPE_METHOD(tpl, ShowWindow);
      CUSTOM_NAN_SET_PROTOTYPE_METHOD(tpl, HideWindow);
      CUSTOM_NAN_SET_PROTOTYPE_METHOD(tpl, toHwnd);
      CUSTOM_NAN_SET_PROTOTYPE_METHOD(tpl, MoveWindow);
      CUSTOM_NAN_SET_PROTOTYPE_METHOD(tpl, toVMrenderhwnd);
      CUSTOM_NAN_SET_PROTOTYPE_METHOD(tpl, Test);

      constructor().Reset(Nan::GetFunction(tpl).ToLocalChecked());
      Nan::Set(target, className, Nan::GetFunction(tpl).ToLocalChecked());
    }

    static NAN_METHOD(NewInstance)
    {
      auto cons = Nan::New(constructor());
      info.GetReturnValue().Set(Nan::NewInstance(cons, 0, nullptr).ToLocalChecked());
    }

  private:
    explicit Tools();
    ~Tools();

    static void DisposeAll(void* data) {
        auto runtime = static_cast<Tools*>(data);
        delete runtime;
    }

    static NAN_METHOD(New)
    {
      if (info.IsConstructCall())
      {
        auto obj = new Tools();
#if NODE_VERSION_AT_LEAST(11, 0, 0)
        node::AddEnvironmentCleanupHook(info.GetIsolate(), DisposeAll, obj);
#else                                                                   
        node::AtExit(DisposeAll, obj);
#endif
        obj->Wrap(info.This());
        info.GetReturnValue().Set(info.This());
      }
      else
      {
        auto cons = Nan::New(constructor());
        info.GetReturnValue().Set(Nan::NewInstance(cons, 0, nullptr).ToLocalChecked());
      }
    }

    static inline Nan::Persistent<v8::Function> &constructor()
    {
      static Nan::Persistent<v8::Function> my_constructor;
      return my_constructor;
    }

  public:
    CUSTOM_NAN_METHOD(Tools, ShowWindow)
    CUSTOM_NAN_METHOD(Tools, HideWindow)
    CUSTOM_NAN_METHOD(Tools, toHwnd)
    CUSTOM_NAN_METHOD(Tools, MoveWindow)
    CUSTOM_NAN_METHOD(Tools, toVMrenderhwnd)
    CUSTOM_NAN_METHOD(Tools, Test)

  };

}

#endif